import { useState, useRef, useEffect, useCallback } from 'react';
import { Box, Button, TextField, Stack, FormControl, InputLabel, Select, MenuItem, CircularProgress, Typography } from '@mui/material';
import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Cancel';
import DeleteIcon from '@mui/icons-material/Delete';
import dayjs from 'dayjs';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
import { roomService, bookingService } from '../../../services';
import { useMessage } from '../../../hooks';
import { ConfirmDialog } from '../../../components'

const BookingForm = ({
  booking,
  mode = 'create', // create/edit
  variant = 'page', // page/dialog
  loading: externalLoading,
  onSave,
  onCancel,
  onDelete,
  saveButtonText,
  cancelButtonText,
  children
}) => {
  const getInitialState = useCallback(() => ({
    title: '',
    description: '',
    roomId: '',
    id: '',
    start: dayjs().add(30, 'minute'),
    end: dayjs().add(1.5, 'hour'),
    ...(booking && {
      title: booking.title || '',
      description: booking.description || '',
      roomId: booking.roomId || '',
      id: booking.id || '',
      start: booking.start ? dayjs(booking.start) : dayjs().add(30, 'minute'),
      end: booking.end ? dayjs(booking.end) : dayjs().add(1.5, 'hour')
    })
  }), [booking]);

  const message = useMessage();
  const [formData, setFormData] = useState(getInitialState);
  const [rooms, setRooms] = useState([]);
  const [internalLoading, setInternalLoading] = useState(false);
  const [errors, setErrors] = useState({});
  const titleRef = useRef(null);

  const isLoading = externalLoading || internalLoading;
  const [openConfirm, setOpenConfirm] = useState(false);
  const fetchRooms = useCallback(async () => {
    try {
      setInternalLoading(true);
      const response = await roomService.getRooms(0, 100);
      setRooms(response?.items || []);
      // 当在编辑模式时保留已有数据
      setFormData(prev => mode === 'edit' ? prev : getInitialState());
    } catch (err) {
      console.error('Failed to load rooms', err);
    } finally {
      setInternalLoading(false);
    }
  }, [getInitialState, mode]);

  useEffect(() => {
    fetchRooms();
  }, [fetchRooms]);

  const validateForm = useCallback(() => {
    const newErrors = {};
    if (!formData.title) newErrors.title = 'Title is required';
    if (!formData.roomId) newErrors.roomId = 'Room is required';
    if (!formData.start) newErrors.start = 'Start time is required';
    if (!formData.end) newErrors.end = 'End time is required';
    if (formData.start?.isAfter(formData.end)) {
      newErrors.end = 'End time must be after start time';
    }
    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  }, [formData]);

  const handleSubmit = useCallback(async (e) => {
    e?.preventDefault();
    if (!validateForm()) return;

    setInternalLoading(true);
    try {
      const bookingData = {
        ...(mode === 'edit' && { id: formData.id }),
        StartDate: formData.start,
        EndDate: formData.end,
        RoomId: formData.roomId,
        Title: formData.title,
        Description: formData.description,
      };

      if (onSave) {
        await onSave(bookingData);
      }
      else {
        const operation = mode === 'edit'
          ? bookingService.updateBooking
          : bookingService.createBooking;

        await operation(bookingData);
      }
    } catch (err) {
      message.showError(err || 'Failed to create booking');
    }
    finally {
      setInternalLoading(false);
    }
  }, [formData, mode, onSave, validateForm]);

  const onYes = () => {
    if (onDelete) {
      onDelete(formData);
    } else {
      bookingService.deleteBooking(formData.id)
        .then(() => {
          message.showSuccess('Booking deleted successfully');
          onCancel();
        })
        .catch(err => {
          message.showError(err || 'Failed to delete booking');
        });
    }
  }  
  const handlePropertyChange = useCallback((field) => (value) => {
    setFormData(prev => ({
      ...prev,
      [field]: value?.target?.value ?? value
    }));
    setErrors(prev => ({ ...prev, [field]: '' }));
  }, []);

  return (
    <>
      <LocalizationProvider dateAdapter={AdapterDayjs}>
        <Box
          sx={{
            ...(variant === 'page' && {
              maxWidth: 800,
              mx: 'auto',
              p: 3,
              bgcolor: 'background.paper',
              borderRadius: 2,
              boxShadow: 1
            })
          }}
        >
          {variant === 'page' && (
            <Typography variant="h5" gutterBottom>
              {mode === 'edit' ? 'Edit Booking' : 'Create New Booking'}
            </Typography>
          )}

          <form onSubmit={handleSubmit}>
            <Stack spacing={3} marginTop={2}>
              <TextField
                required
                label="Title"
                value={formData.title}
                onChange={handlePropertyChange('title')}
                error={!!errors.title}
                helperText={errors.title}
                disabled={isLoading}
                inputRef={titleRef}
              />
              <FormControl required error={!!errors.roomId}>
                <InputLabel>Room</InputLabel>
                <Select
                  value={formData.roomId}
                  label="Room"
                  onChange={handlePropertyChange('roomId')}
                  disabled={isLoading}
                >
                  <MenuItem value=""><em>Select a room</em></MenuItem>
                  {rooms.map(room => (
                    <MenuItem key={room.id} value={room.id}>{room.name}</MenuItem>
                  ))}
                </Select>
                {errors.roomId && (
                  <Typography color="error" variant="caption">
                    {errors.roomId}
                  </Typography>
                )}
              </FormControl>

              <Stack spacing={2}>
                <DateTimePicker
                  label="Start Time"
                  value={formData.start}
                  onChange={handlePropertyChange('start')}
                  disabled={isLoading}
                  slotProps={{
                    textField: {
                      required: true,
                      error: !!errors.start,
                      helperText: errors.start
                    }
                  }}
                />
                <DateTimePicker
                  label="End Time"
                  value={formData.end}
                  onChange={handlePropertyChange('end')}
                  disabled={isLoading}
                  slotProps={{
                    textField: {
                      required: true,
                      error: !!errors.end,
                      helperText: errors.end
                    }
                  }}
                />
              </Stack>

              <TextField
                label="Description"
                value={formData.description}
                onChange={handlePropertyChange('description')}
                multiline
                rows={4}
                disabled={isLoading}
              />

              {children}

              <Stack direction="row" spacing={2} justifyContent="flex-end">

                <Button
                  variant="outlined"
                  startIcon={<CancelIcon />}
                  onClick={onCancel}
                  disabled={isLoading}
                >
                  {cancelButtonText || 'Cancel'}
                </Button>
                {mode === 'edit' ?
                  <Button
                    color="error"
                    variant="outlined"
                    startIcon={<DeleteIcon />}
                    onClick={()=>setOpenConfirm(true)}
                    disabled={isLoading}
                  >
                    {isLoading ? (
                      <CircularProgress size={24} />
                    ) : 'Delete'}
                  </Button>
                  : null}
                <Button
                  type="submit"
                  variant="contained"
                  startIcon={<SaveIcon />}
                  disabled={isLoading}
                >
                  {isLoading ? (
                    <CircularProgress size={24} />
                  ) : (
                    saveButtonText || (mode === 'edit' ? 'Save Changes' : 'Create Booking')
                  )}
                </Button>
              </Stack>
            </Stack>
          </form>
        </Box>
      </LocalizationProvider>
      <ConfirmDialog message={'Are you sure you want to delete this room?'} open={openConfirm} onYes={onYes} onNo={()=>setOpenConfirm(false)} />
    </>

  );

};

export default BookingForm;